package com.legstar.talend.xsd2xml;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import java.util.Map;

import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaCollection;

import com.legstar.xsd.InvalidXsdException;
import com.legstar.xsd.XsdMappingException;

/**
 * API that translates COBOL-annotated XML schema to TOS Schemas.
 * <p/>
 * One COBOL-annotated XML schema may translate to more than one TOS schema
 * because choices (REDEFINES) are segregated in different TOS schema.
 * 
 */
public class Cob2TosSchema {

    /**
     * Translate a COBOL-annotated XML schema to a set of TOS schemas.
     * 
     * @param cobXsd the COBOL-annotated XML schema content
     * @return a TOS schema serialized in a string
     * @throws InvalidXsdException if parsing or mapping fails
     */
    public Map<String, String> translate(final String cobXsd)
            throws InvalidXsdException {
        Cob2TosSchemaWriter writer = new Cob2TosSchemaWriter(
                toTosSchemas(cobXsd));
        return writer.toStrings();
    }

    /**
     * Translate a COBOL-annotated XML schema to a set of TOS schemas.
     * 
     * @param cobXsd the COBOL-annotated XML schema content
     * @param outputFolder the output folder to receive TOS schemas
     * @param hintBaseName the name to use as base for output files
     * @throws InvalidXsdException if parsing or mapping fails
     */
    public List<File> translate(final String cobXsd, final File outputFolder,
            final String hintBaseName) throws InvalidXsdException {
        try {
            Cob2TosSchemaWriter writer = new Cob2TosSchemaWriter(
                    toTosSchemas(cobXsd));
            return writer.toFiles(outputFolder, hintBaseName);
        } catch (IOException e) {
            throw new InvalidXsdException(e);
        }
    }

    /**
     * Translate a COBOL-annotated XML schema to a set of TOS schemas.
     * 
     * @param cobXsd the COBOL-annotated XML schema content
     * @return a map of TOS schemas, each identified with a unique name
     * @throws InvalidXsdException if parsing or mapping fails
     */
    public Map<String, TosSchema> toTosSchemas(final String cobXsd)
            throws InvalidXsdException {
        try {
            XmlSchemaCollection schemaCol = new XmlSchemaCollection();
            XmlSchema xsd = schemaCol.read(new StringReader(cobXsd), null);
            Cob2XsdSchemaNavigator visitor = new Cob2XsdSchemaNavigator(xsd);
            visitor.visit();
            Cob2TosSchemaPostProcessor postProcessor = new Cob2TosSchemaPostProcessor();
            return postProcessor.splitChoices(visitor.getTosSchema());
        } catch (XsdMappingException e) {
            throw new InvalidXsdException(e);
        }
    }
}
